package com.ucode.wap.cgms.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ucode.cgms.api.CgmsSysConfigRemoteApi;
import com.ucode.cgms.service.*;
import com.ucode.member.service.MemberService;
import com.ucode.model.cgms.*;
import com.ucode.model.cgms.convert.CgmsCompanionOrderConvert;
import com.ucode.model.cgms.convert.CgmsCompanionOrderReportLogConvert;
import com.ucode.model.cgms.convert.CgmsJointServiceUserConvert;
import com.ucode.model.cgms.enums.CgmsCompanionOrderStatusEnum;
import com.ucode.model.cgms.enums.CgmsCompanionReportAuditStateEnum;
import com.ucode.model.cgms.enums.CgmsSysResultCodeEnum;
import com.ucode.model.cgms.form.CgmsCompanionOrderCreateForm;
import com.ucode.model.cgms.form.CgmsCompanionOrderReportForm;
import com.ucode.model.cgms.form.CgmsJointServiceUserAddForm;
import com.ucode.model.cgms.vo.CgmsCompanionOrderReportLogVO;
import com.ucode.model.cgms.vo.CgmsCompanionOrderVO;
import com.ucode.model.cgms.vo.CgmsJointServiceUserVO;
import com.ucode.model.member.Member;
import com.ucode.model.pay.order.dto.PayOrderCreateReqDTO;
import com.ucode.pay.service.PayOrderService;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.base.enums.UserTypeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.CollectionUtils;
import com.ucode.tool.util.ServletUtils;
import com.ucode.wap.base.core.CurrentLoginUserHandler;
import com.ucode.wap.cgms.service.ApiCgmsCompanionOrderService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class ApiCgmsCompanionOrderServiceImpl implements ApiCgmsCompanionOrderService {

    @Resource
    private CgmsCompanionOrderService cgmsCompanionOrderService;
    @Resource
    private CgmsCompanionProductService cgmsCompanionProductService;
    @Resource
    private CgmsJointServiceUserService cgmsJointServiceUserService;
    @Resource
    private CgmsCompanionOrderReportLogService cgmsCompanionOrderReportLogService;
    @Resource
    private CgmsCompanionUserService cgmsCompanionUserService;
    @Resource
    private MemberService memberService;
    @Resource
    private CgmsSysConfigRemoteApi cgmsSysConfigRemoteApi;
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private CurrentLoginUserHandler currentLoginUserHandler;

    @Override
    public Long submitOrder(CgmsCompanionOrderCreateForm form) {

        //验证服务商品
        CgmsCompanionProduct companionProduct = cgmsCompanionProductService.validateRelease(form.getProductId());

        //创建订单
        CgmsCompanionOrder companionOrder = CgmsCompanionOrderConvert.INSTANCE.build(form, companionProduct);
        companionOrder.setMemberId(currentLoginUserHandler.getCurrentUserId());
        companionOrder.setUserIp(ServletUtils.getClientIP());
        companionOrder.setStatus(CgmsCompanionOrderStatusEnum.PENDING_PAYMENT.getState());
        companionOrder.setReportAuditState(CgmsCompanionReportAuditStateEnum.AWAIT.getCode());
        companionOrder.setRefundQuantity(0);
        companionOrder.setRefundAmount(BigDecimal.ZERO);

        //接单人,直接找陪玩点单，需要设置接单人
        if(!ObjUtil.equals(companionProduct.getProviderId(), 0L)){
            companionOrder.setServiceUserId(companionProduct.getProviderId());
            companionOrder.setDispatchedTime(LocalDateTime.now());
        }

        //支付过期时间,默认30分钟
        LocalDateTime expireTime = LocalDateTimeUtil.offset(LocalDateTimeUtil.now(),30, ChronoUnit.MINUTES);
        companionOrder.setExpireTime(expireTime);

        Long orderId = cgmsCompanionOrderService.insert(companionOrder);

        //目前仅支持微信支付

        //6、生成统一支付订单
        String userIp = companionOrder.getUserIp();
        Long merchantOrderNo = orderId;
        Integer amount = NumberUtil.mul(companionOrder.getPayPrice(),100).intValue();
        String serviceNotifyUrl = cgmsSysConfigRemoteApi.getCompanionOrderPayNotifyUrl();
        Long payOrderId = createPayOrder(form.getPayAppId(), companionOrder.getMemberId(), UserTypeEnum.MEMBER.getCode(), userIp, merchantOrderNo.toString(), amount, expireTime, serviceNotifyUrl);
        return payOrderId;
    }

    @Override
    public Long continuePay(Long orderId, Long payAppId) {
        CgmsCompanionOrder companionOrder = cgmsCompanionOrderService.validate(orderId);
        //支付状态
        if(!ObjUtil.equals(companionOrder.getStatus(),CgmsCompanionOrderStatusEnum.PENDING_PAYMENT.getCode())){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_STATUS_IS_NOT_WAITING);
        }

        //订单是否已过期
        if(!companionOrder.getExpireTime().isAfter(LocalDateTime.now())){
            //取消订单
            cgmsCompanionOrderService.cancel(orderId);
            throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_IS_EXPIRED);
        }

        String userIp = ServletUtils.getClientIP();
        Long merchantOrderNo = orderId;
        LocalDateTime expireTime = companionOrder.getExpireTime();
        Integer amount = NumberUtil.mul(companionOrder.getPayPrice(),100).intValue();
        String serviceNotifyUrl = cgmsSysConfigRemoteApi.getCompanionOrderPayNotifyUrl();
        Long payOrderId = createPayOrder(payAppId, companionOrder.getMemberId(), UserTypeEnum.MEMBER.getCode(), userIp, merchantOrderNo.toString(), amount, expireTime, serviceNotifyUrl);

        //默认支付通过（测试环境）,切记后续要删掉
        //paySuccess(orderId,payOrderId, PayTypeEnum.WX_LITE.getCode(),LocalDateTime.now(),amount);
        return payOrderId;
    }

    @Override
    public void updateRemark(Long orderId, String remark) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.updateRemarkByMember(userId,orderId,remark);
    }

    @Override
    public void cancel(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.cancelByMember(userId,orderId);
    }

    @Override
    public void confirmCompleted(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.confirmCompleted(userId,orderId);
    }

    @Override
    public void confirmReceive(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.confirmReceiveByMember(userId,orderId);
    }

    @Override
    public void refuseReceive(Long orderId) {
        //驳回订单
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.refuseReceiveByMember(userId,orderId);
    }

    @Override
    public void companionReport(CgmsCompanionOrderReportForm companionOrderReportForm) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.companionReport(userId,companionOrderReportForm.getId(),companionOrderReportForm.getServiceStartTime(),companionOrderReportForm.getServiceEndTime(),companionOrderReportForm.getEvidencePics(),companionOrderReportForm.getEvidenceRemark());
    }

    @Override
    public void addJointServiceUser(CgmsJointServiceUserAddForm form) {
        Long userId = currentLoginUserHandler.getCurrentUserId();

        List<CgmsJointServiceUser> jointServiceUsers = new ArrayList<>();
        for(CgmsJointServiceUserAddForm.JointServiceUserItem item : form.getItems()){
            CgmsJointServiceUser bean = new CgmsJointServiceUser();
            bean.setOrderId(form.getOrderId());
            bean.setServiceUserId(item.getServiceUserId());
            bean.setAmount(item.getAmount());
            jointServiceUsers.add(bean);
        }
        cgmsCompanionOrderService.addJointServiceUser(userId,form.getOrderId(),jointServiceUsers);
    }

    @Override
    public void paySuccess(Long orderId, Long payOrderId, String payType, LocalDateTime payTime, Integer payAmount) {
        cgmsCompanionOrderService.paySuccess(orderId, payOrderId,payType , payTime,payAmount);
    }

    @Override
    public void delete(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.deleteByMember(userId,orderId);
    }

    @Override
    public CgmsCompanionOrderVO detail(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        CgmsCompanionOrder bean = cgmsCompanionOrderService.selectByPrimaryKey(orderId);
        if(ObjUtil.isNull(bean)){
            throw new UcodeServiceException(CgmsSysResultCodeEnum.COMPANION_ORDER_NOT_EXISTS);
        }

        if(!ObjUtil.equals(bean.getMemberId(),userId) && !ObjUtil.equals(bean.getServiceUserId(),userId)){
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }

        CgmsCompanionOrderVO beanVO = CgmsCompanionOrderConvert.INSTANCE.convert(bean);

        Member member = memberService.selectByPrimaryKey(beanVO.getMemberId());
        if(ObjUtil.isNotNull(member)){
            beanVO.setMemberNickname(member.getNickname());
            beanVO.setMemberAvatar(member.getAvatar());
        }

        Set<Long> serviceUserIds = new HashSet<>();
        serviceUserIds.add(bean.getServiceUserId());

        //查询联合服务人列表
        List<CgmsJointServiceUser> jointServiceUserList = cgmsJointServiceUserService.queryListByOrderId(bean.getId());
        if(CollUtil.isNotEmpty(jointServiceUserList)) {
            serviceUserIds.addAll(CollectionUtils.convertSet(jointServiceUserList, CgmsJointServiceUser::getServiceUserId));
        }

        //查询报备日志列表
        List<CgmsCompanionOrderReportLog> reportLogs = cgmsCompanionOrderReportLogService.queryListByOrderId(bean.getId());
        if(CollUtil.isNotEmpty(reportLogs)){
            serviceUserIds.addAll(CollectionUtils.convertSet(reportLogs, CgmsCompanionOrderReportLog::getServiceUserId));
        }

        Map<Long, CgmsCompanionUser>  companionUserMap = cgmsCompanionUserService.getMap(serviceUserIds);

        if(CollUtil.isNotEmpty(reportLogs)){
            List<CgmsCompanionOrderReportLogVO>  reportLogsVo = CgmsCompanionOrderReportLogConvert.INSTANCE.convertList(reportLogs);
            for(CgmsCompanionOrderReportLogVO vo : reportLogsVo){
                CgmsCompanionUser user = companionUserMap.get(vo.getServiceUserId());
                if(ObjUtil.isNotNull(user)){
                    vo.setNickname(user.getNickName());
                    vo.setAvatar(user.getAvatar());
                }
            }

            beanVO.setReportLogs(reportLogsVo);
        }


        if(CollUtil.isNotEmpty(jointServiceUserList)) {
            List<CgmsJointServiceUserVO> jointServiceUserVo = CgmsJointServiceUserConvert.INSTANCE.convertList(jointServiceUserList);
            for (CgmsJointServiceUserVO vo : jointServiceUserVo){
                CgmsCompanionUser serviceUser = companionUserMap.get(vo.getServiceUserId());
                if(ObjectUtil.isNotEmpty(serviceUser)){
                    vo.setNickname(serviceUser.getNickName());
                    vo.setAvatar(serviceUser.getAvatar());
                }

            }
            beanVO.setJointServiceUserList(jointServiceUserVo);
        }

        CgmsCompanionUser serviceUser = companionUserMap.get(beanVO.getServiceUserId());
        if(ObjectUtil.isNotEmpty(serviceUser)){
            beanVO.setServiceUserNickname(serviceUser.getNickName());
            beanVO.setServiceUserAvatar(serviceUser.getAvatar());
            beanVO.setServicePhone(serviceUser.getPhone());
        }
        return beanVO;
    }

    @Override
    public Paginator<CgmsCompanionOrderVO> pageList(Map<String, Object> condition,Integer pageSize, Integer pageNum) {
        Paginator<CgmsCompanionOrder> paginator = cgmsCompanionOrderService.queryPageForList(condition, pageSize, pageNum);
        Paginator<CgmsCompanionOrderVO> paginatorVO = CgmsCompanionOrderConvert.INSTANCE.convertPage(paginator);
        if(CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> memberIds = new HashSet<>();
            Set<Long> serviceUserIds = new HashSet<>();

            // 收集ID
            for(CgmsCompanionOrderVO vo : paginatorVO.getList()){
                if (ObjUtil.isNotNull(vo.getMemberId())) {
                    memberIds.add(vo.getMemberId());
                }

                if(ObjUtil.isNotNull(vo.getServiceUserId()) && !ObjUtil.equals(vo.getServiceUserId(), 0L)) {
                    serviceUserIds.add(vo.getServiceUserId());
                }
            }

            // 批量查询
            Map<Long, Member> memberMap = CollUtil.isEmpty(memberIds) ? new HashMap<>() : memberService.getMap(memberIds);
            Map<Long, CgmsCompanionUser> serviceUserMap = CollUtil.isEmpty(serviceUserIds) ? new HashMap<>() : cgmsCompanionUserService.getMap(serviceUserIds);

            // 填充数据
            for(CgmsCompanionOrderVO vo : paginatorVO.getList()) {
                // 填充会员信息
                if (ObjUtil.isNotNull(vo.getMemberId())) {
                    Member member = memberMap.get(vo.getMemberId());
                    if(ObjUtil.isNotNull(member)) {
                        vo.setMemberNickname(member.getNickname());
                        vo.setMemberAvatar(member.getAvatar());
                    }
                }

                // 填充服务人员信息
                if(ObjUtil.isNotNull(vo.getServiceUserId()) && !ObjUtil.equals(vo.getServiceUserId(), 0L)) {
                    CgmsCompanionUser serviceUser = serviceUserMap.get(vo.getServiceUserId());
                    if(ObjUtil.isNotNull(serviceUser)) {
                        if(ObjUtil.isNotNull(serviceUser)) {
                            vo.setServiceUserNickname(serviceUser.getNickName());
                            vo.setServicePhone(serviceUser.getPhone());
                            vo.setServiceUserAvatar(serviceUser.getAvatar());
                        }
                    }
                }
            }
        }
        return paginatorVO;
    }

    @Override
    public List<CgmsCompanionOrderVO> queryCompanionUserSnatchOrderList() {
        List<CgmsCompanionOrder> list = cgmsCompanionOrderService.queryCompanionUserSnatchOrderList();
        List<CgmsCompanionOrderVO>  vos = CgmsCompanionOrderConvert.INSTANCE.convertList(list);
        return vos;
    }

    @Override
    public void snatchOrder(Long orderId) {
        Long userId = currentLoginUserHandler.getCurrentUserId();
        cgmsCompanionOrderService.snatchOrder(userId, orderId);
    }

    /**
     * 创建支付订单
     * @param appId
     * @param userId
     * @param userType
     * @param userIp
     * @param merchantOrderNo
     * @param amount
     * @param expireTime
     * @param serviceNotifyUrl
     * @return 支付订单ID
     */
    private Long createPayOrder(Long appId, Long userId, Integer userType, String userIp, String merchantOrderNo, Integer amount, LocalDateTime expireTime, String serviceNotifyUrl) {
        // 创建支付单，用于后续的支付
        PayOrderCreateReqDTO payOrderCreateReqDTO = new PayOrderCreateReqDTO();
        payOrderCreateReqDTO.setAppId(appId);
        payOrderCreateReqDTO.setUserId(userId);
        payOrderCreateReqDTO.setUserType(userType);
        payOrderCreateReqDTO.setUserIp(userIp);
        payOrderCreateReqDTO.setMerchantOrderNo(merchantOrderNo);
        payOrderCreateReqDTO.setSubject("购买商品");
        payOrderCreateReqDTO.setBody("");
        payOrderCreateReqDTO.setCurrency("CNY");
        payOrderCreateReqDTO.setAmount(amount);
        payOrderCreateReqDTO.setExpireTime(expireTime);
        payOrderCreateReqDTO.setServiceNotifyUrl(serviceNotifyUrl);
        Long payOrderId =  payOrderService.create(payOrderCreateReqDTO);
        if(ObjUtil.isNull(payOrderId)) {
            throw new UcodeServiceException(GlobalResultCodeEnum.FAILED.getCode(), "提交支付失败,请稍后重试");
        }
        return payOrderId;
    }

}
